/*
 * Saphre - Suffix Arrays for Phrase Extraction
 * Copyright (C) 2013 
 * Dale Gerdemann - Tübingen, Germany 
 * Niko Schenk - Frankfurt am Main, Germany
 * All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */
package util;

import saphre.core.SuffixArray;
import saphre.core.Store;


/**
 * A pretty printer mostly interesting to programmers.
 */
public class PPrint {

    public static void ppInterval(SuffixArray sa, SuffixArray pa, Store store,
                                  int depth, int lb, int rb) {
        int[] suftab = sa.getSuftab();
        int[] preftab = pa.getSuftab();
        int N = sa.getText().length - 1;
        int[] len = new int[rb - lb + 1];
        len[0] = 2;
        for (int i = 0; i <= depth; i++) {
            for (int j = lb, k = 0; j <= rb; j++, k++) {
                int pos1 = suftab[j] + i;
                if (pos1 < suftab.length) {
                    int length1 = store.toString(pos1, pos1 + 1).length();
                    if (length1 > len[k]) {
                        len[k] = length1;
                    }
                }
                int pos2 = preftab[j] - i;
                if (pos2 > 0) {
                    int length2 = store.toString(pos2, pos2 + 1).length();
                    if (length2 > len[k]) {
                        len[k] = length2;
                    }
                }
            }
        }


        int[] pLcp = pa.getLcptab();
        int[] sLcp = sa.getLcptab();
        int[] pCld = pa.getCldtab();
        int[] sCld = sa.getCldtab();
        int[] pSuf = pa.getSuftab();
        int[] sSuf = sa.getSuftab();

        for (int j = lb, k = 0; j <= rb; j++, k++) {
            len[k] = Math.max(len[k], ("" + k).length());
            len[k] = Math.max(len[k], ("" + pLcp[j]).length());
            len[k] = Math.max(len[k], ("" + sLcp[j]).length());
            len[k] = Math.max(len[k], ("" + pCld[j]).length());
            len[k] = Math.max(len[k], ("" + sCld[j]).length());
            len[k] = Math.max(len[k], ("" + pSuf[j]).length());
            len[k] = Math.max(len[k], ("" + sSuf[j]).length());
        }

        String[] format = new String[len.length];
        for (int i = 0; i < format.length; i++) {
            format[i] = "%-" + len[i] + "s|";
        }


        for (int i = depth; i >= 0; i--) {
            System.out.print("        |");
            for (int j = lb, k = 0; j <= rb; j++, k++) {
                int pos = preftab[j] - i;
                if (pos > 0) {
                    System.out.printf(format[k], store.toString(pos, pos + 1));
                }
                else {
                    System.out.printf(format[k], "");
                }
            }
            System.out.println();
        }
        System.out.println();

        for (int i = 0; i <= depth; i++) {
            System.out.print("        |");
            for (int j = lb, k = 0; j <= rb; j++, k++) {
                int pos = suftab[j] + i;
                if (pos <= N) {
                    String s = store.toString(pos, pos + 1);
                    int t = s.indexOf("\n");
                    if (t != -1) {
                        s = "";
                    }
                    System.out.printf(format[k], s);
                }
                else {
                    System.out.printf(format[k], "");
                }
            }
            System.out.println();
        }
        System.out.println();


        System.out.print("   idx: |");
        for (int j = lb, k = 0; j <= rb; j++, k++) {
            System.out.printf(format[k], j % (int) Math.pow(10, len[k]));
        }
        System.out.println();
        System.out.print("pa:Lcs: |");
        for (int j = lb, k = 0; j <= rb; j++, k++) {
            System.out.printf(format[k], pLcp[j]);
        }
        System.out.println();
        System.out.print("sa:Lcp: |");
        for (int j = lb, k = 0; j <= rb; j++, k++) {
            System.out.printf(format[k], sLcp[j]);
        }

        System.out.println();
        System.out.print("pa:Cld: |");
        for (int j = lb, k = 0; j <= rb; j++, k++) {
            System.out.printf(format[k], pCld[j]);
        }
        System.out.println();
        System.out.print("sa:Cld: |");
        for (int j = lb, k = 0; j <= rb; j++, k++) {
            System.out.printf(format[k], sCld[j]);
        }
        System.out.println();
        System.out.print("pa:Prf: |");
        for (int j = lb, k = 0; j <= rb; j++, k++) {
            System.out.printf(format[k], pSuf[j]);
        }
        System.out.println();
        System.out.print("sa:Suf: |");
        for (int j = lb, k = 0; j <= rb; j++, k++) {
            System.out.printf(format[k], sSuf[j]);
        }
        System.out.println();
    }


    public static void printPreftab(int[] suftab, Store store) {
        printPreftab(suftab, store, 5);
    }

    public static void printPreftab(int[] suftab, Store store, int depth) {
        for (int i = 0; i < depth; i++) {
            System.out.print("          ");
            for (int j = 1; j < suftab.length; j++) {
                int pos = suftab[j] - i;
                if (pos > 0) {
                    System.out.print(store.toString(pos, pos + 1) + "| ");
                }
            }
        }
    }

    public static void printInvertedPreftab(int[] suftab, Store store,
                                            int lb, int rb) {
        printInvertedPreftab(suftab, store, 5, lb, rb);
    }

    public static void printInvertedPreftab(int[] suftab, Store store,
                                            int depth, int lb, int rb) {
        for (int i = depth; i >= 0; i--) {
            System.out.print("          ");
            for (int j = lb; j <= rb; j++) {
                int pos = suftab[j] - i;
                if (pos > 0) {
                    System.out.print(store.toString(pos, pos + 1) + "| ");
                }
                else {
                    System.out.print(" | ");
                }
            }
            System.out.println();
        }
        System.out.println();
    }

    public static void printSuftab(int[] suftab, Store store) {
        for (int i = 0; i < 5; i++) {
            System.out.print("          ");
            for (int j = 1; j < suftab.length; j++) {
                int pos = suftab[j] + i;
                if (pos < store.text.length) {
                    System.out.print(store.toString(pos, pos + 1) + "| ");
                }
                else {
                    System.out.print(" | ");
                }
            }
            System.out.println();
        }
        System.out.println();

    }

    public static void printSuftab(int[] suftab, Store store, int lb, int rb) {
        for (int i = 0; i < 5; i++) {
            System.out.print("          ");
            for (int j = lb; j <= rb; j++) {
                int pos = suftab[j] + i;
                if (pos < store.text.length) {
                    System.out.print(store.toString(pos, pos + 1) + "| ");
                }
                else {
                    System.out.print(" | ");
                }
            }
            System.out.println();
        }
        System.out.println();
    }
}
